package com.itfreer.sso.service;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.itfreer.sso.share.entity.ResponseResult;
import com.itfreer.sso.share.service.TicketsService;
import com.itfreer.utils.HeaderUtils;
import com.itfreer.utils.json.JsonUtils;
import com.itfreer.utils.sys.SystemParameter;

/**
 * 定义OSS的主要RESTful接口，用于发放和删除TGTs，以及发放STs
 */
@Component("RestTicketsService")
public class RestTicketsService implements TicketsService {

	private final String createTicketGrantingTicketUrl = "/v1/tickets";
	private final String ticketsValidateUrl = "/ticketsValidate";
	private final String createServiceTicketUrl = "/v1/serviceTickets";
	private final String createProxyGrantingTicketUrl = "/v1/proxyGrantingTickets";
	private final String createProxyTicketUrl = "/v1/proxyTickets";
	private final String getTicketStatusUrl = "/v1/tickets";
	private final String deleteTicketGrantingTicketUrl = "/v1/tickets";

	@Autowired
	private SystemParameter systemParameter;

	/**
	 * 发放TGT
	 *
	 * @param ui
	 *            包含用户名与密码的uri信息
	 * @return Response 响应值
	 * @throws IOException
	 */
	@SuppressWarnings("unchecked")
	public ResponseResult createTicketGrantingTicket(String username, String password) throws IOException {
		Client client = ClientBuilder.newClient();
		WebTarget target = client.target(systemParameter.getRemoteUrl() + createTicketGrantingTicketUrl);
		Response response = target.queryParam("username", username).queryParam("password", password).request()
				.headers(HeaderUtils.getSysHeader(systemParameter.getsId(), systemParameter.getsPwd()))
				.buildPost(null).invoke();

		String msg = response.readEntity(String.class);
		Map<String, Object> map = null;
		if (msg.startsWith("{") && msg.endsWith("}")) {
			map = JsonUtils.toBean(msg, Map.class);
		} else {
			map = new HashMap<String, Object>();
			map.put("error", msg);
		}
		ResponseResult result = new ResponseResult(response.getStatus(), map);
		response.close();
		return result;
	}

	/**
	 * TGT验证
	 */
	@SuppressWarnings("unchecked")
	public final ResponseResult ticketsValidate(final String tgtId) {
		Client client = ClientBuilder.newClient();
		WebTarget target = client.target(systemParameter.getRemoteUrl() + ticketsValidateUrl + "/" + tgtId);
		Response response = target.request()
				.headers(HeaderUtils.getSysHeader(systemParameter.getsId(), systemParameter.getsPwd()))
				.buildPost(null).invoke();

		String msg = response.readEntity(String.class);
		Map<String, Object> map = null;
		if (msg.startsWith("{") && msg.endsWith("}")) {
			try {
				map = JsonUtils.toBean(msg, Map.class);
			} catch (IOException e) {
				e.printStackTrace();
			}
		} else {
			map = new HashMap<String, Object>();
			map.put("error", msg);
		}
		ResponseResult result = new ResponseResult(response.getStatus(), map);
		response.close();
		return result;
	}

	/**
	 * 发放ST
	 *
	 * @param serviceId
	 *            注册服务
	 * @param tgtId
	 *            tgt
	 * @return Response 响应值
	 * @throws IOException
	 */
	@SuppressWarnings("unchecked")
	public ResponseResult createServiceTicket(String tgtId, String serviceId) throws IOException {
		Client client = ClientBuilder.newClient();
		WebTarget target = client.target(systemParameter.getRemoteUrl() + createServiceTicketUrl + "/" + tgtId);
		Response response = target.queryParam("service", serviceId).request()
				.headers(HeaderUtils.getSysHeader(systemParameter.getsId(), systemParameter.getsPwd()))
				.buildPost(null).invoke();

		String msg = response.readEntity(String.class);
		Map<String, Object> map = null;
		if (msg.startsWith("{") && msg.endsWith("}")) {
			map = JsonUtils.toBean(msg, Map.class);
		} else {
			map = new HashMap<String, Object>();
			map.put("error", msg);
		}
		ResponseResult result = new ResponseResult(response.getStatus(), map);
		response.close();
		return result;
	}

	/**
	 * 发放ST
	 *
	 * @param serviceId
	 *            注册服务
	 * @param tgtId
	 *            tgt
	 * @return Response 响应值
	 * @throws IOException
	 */
	@SuppressWarnings("unchecked")
	public ResponseResult createProxyGrantingTicket(final String serviceTicketId) throws IOException {
		Client client = ClientBuilder.newClient();
		WebTarget target = client
				.target(systemParameter.getRemoteUrl() + createProxyGrantingTicketUrl + "/" + serviceTicketId);
		Response response = target.request()
				.headers(HeaderUtils.getSysHeader(systemParameter.getsId(), systemParameter.getsPwd()))
				.buildPost(null).invoke();

		String msg = response.readEntity(String.class);
		Map<String, Object> map = null;
		if (msg.startsWith("{") && msg.endsWith("}")) {
			map = JsonUtils.toBean(msg, Map.class);
		} else {
			map = new HashMap<String, Object>();
			map.put("error", msg);
		}
		ResponseResult result = new ResponseResult(response.getStatus(), map);
		response.close();
		return result;
	}

	/**
	 * 发放ST
	 *
	 * @param serviceId
	 *            注册服务
	 * @param proxyGrantingTicket
	 *            PGT
	 * @return Response 响应值
	 * @throws IOException
	 */
	@SuppressWarnings("unchecked")
	public ResponseResult createProxyTicket(final String proxyGrantingTicket, final String serviceId)
			throws IOException {
		Client client = ClientBuilder.newClient();
		WebTarget target = client
				.target(systemParameter.getRemoteUrl() + createProxyTicketUrl + "/" + proxyGrantingTicket);
		Response response = target.queryParam("service", serviceId).request()
				.headers(HeaderUtils.getSysHeader(systemParameter.getsId(), systemParameter.getsPwd()))
				.buildPost(null).invoke();

		String msg = response.readEntity(String.class);
		Map<String, Object> map = null;
		if (msg.startsWith("{") && msg.endsWith("}")) {
			map = JsonUtils.toBean(msg, Map.class);
		} else {
			map = new HashMap<String, Object>();
			map.put("error", msg);
		}
		ResponseResult result = new ResponseResult(response.getStatus(), map);
		response.close();
		return result;
	}

	/**
	 * 验证票据状态
	 *
	 * @param id
	 *            ticket id
	 * @return {@link ResponseEntity} representing RESTful response
	 */
	@SuppressWarnings("unchecked")
	public ResponseResult getTicketStatus(final String id) {
		Client client = ClientBuilder.newClient();
		WebTarget target = client.target(systemParameter.getRemoteUrl() + getTicketStatusUrl + "/" + id);
		Response response = target.request()
				.headers(HeaderUtils.getSysHeader(systemParameter.getsId(), systemParameter.getsPwd()))
				.buildGet().invoke();

		String msg = response.readEntity(String.class);
		Map<String, Object> map = null;
		if (msg.startsWith("{") && msg.endsWith("}")) {
			try {
				map = JsonUtils.toBean(msg, Map.class);
			} catch (IOException e) {
				e.printStackTrace();
			}
		} else {
			map = new HashMap<String, Object>();
			map.put("error", msg);
		}
		ResponseResult result = new ResponseResult(response.getStatus(), map);
		response.close();
		return result;
	}

	/**
	 * 销毁tgt
	 *
	 * @param tgtId
	 *            需要销毁的tgt
	 * @return {@link ResponseEntity} representing RESTful response. Signals
	 *         {@link HttpStatus#OK} when successful.
	 */
	@SuppressWarnings("unchecked")
	public ResponseResult deleteTicketGrantingTicket(final String tgtId) {
		Client client = ClientBuilder.newClient();
		WebTarget target = client.target(systemParameter.getRemoteUrl() + deleteTicketGrantingTicketUrl + "/" + tgtId);
		Response response = target.request()
				.headers(HeaderUtils.getSysHeader(systemParameter.getsId(), systemParameter.getsPwd()))
				.buildDelete().invoke();

		String msg = response.readEntity(String.class);
		Map<String, Object> map = null;
		if (msg.startsWith("{") && msg.endsWith("}")) {
			try {
				map = JsonUtils.toBean(msg, Map.class);
			} catch (IOException e) {
				e.printStackTrace();
			}
		} else {
			map = new HashMap<String, Object>();
			map.put("error", msg);
		}
		ResponseResult result = new ResponseResult(response.getStatus(), map);
		response.close();
		return result;
	}
}